package com.example.CarManagement.sys.service.impl;

import cn.hutool.jwt.JWTUtil;
import cn.hutool.jwt.signers.JWTSigner;
import cn.hutool.jwt.signers.JWTSignerUtil;
import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.CarManagement.common.Result;
import com.example.CarManagement.exception.ServiceException;
import com.example.CarManagement.sys.dto.WxUserLogin;
import com.example.CarManagement.sys.entity.*;
import com.example.CarManagement.sys.mapper.*;
import com.example.CarManagement.sys.service.IUserService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.nio.charset.StandardCharsets;
import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * <p>
 * 用户表 服务实现类
 * </p>
 *
 * @author 徐佳彪
 * @since 2025-07-08
 */
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    @Resource
    private AuthenticationManager authenticationManager;


    @Resource
    private RoleMapper roleMapper;

    @Resource
    private UserRoleMapper userRoleMapper;


    @Resource
    private PermissionMapper permissionMapper;

    @Resource
    private RolePermissionMapper rolePermissionMapper;

    // 密码
    BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();


    @Value("${sysRoleId.driver}")
    private String driverRoleId;

    @Value("${sysRoleId.user}")
    private String userRoleId;

    @Value("${sysRoleId.admin}")
    private String adminRoleId;

    @Override
    public Result<?> login(User user) {


        // 用户验证
        Authentication authentication = null;
        try {
            UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(user.getUsername(), user.getPassword());
            // 该方法会去调用UserDetailsServiceImpl.loadUserByUsername
            authentication = authenticationManager.authenticate(authenticationToken);
        } catch (Exception e) {
            throw new ServiceException(e.getMessage());
        }
        if (authentication == null) {
            throw new ServiceException("登录失败");
        }


        // 用户权限信息
        LoginUser userDetails = (LoginUser) authentication.getPrincipal();


        Map<String, Object> principal = new HashMap<>();
        principal.put("userId", userDetails.getUserId());
        principal.put("loginTime", LocalDateTime.now());

//        查询用户角色
        try {
            LambdaQueryWrapper<UserRole> userRoleWrapper = new LambdaQueryWrapper<>();
            userRoleWrapper.eq(UserRole::getUserId, userDetails.getUserId());
            UserRole userRole = userRoleMapper.selectOne(userRoleWrapper);
            Role role = roleMapper.selectById(userRole.getRoleId());

            // 查询角色对应的权限，并配置
            LambdaQueryWrapper<RolePermission> roleQueryWrapper = new LambdaQueryWrapper<>();
            roleQueryWrapper.eq(RolePermission::getRoleId, role.getId());
            List<RolePermission> rolePermissions = rolePermissionMapper.selectList(roleQueryWrapper);
            List<String> rolePermissionIds = new ArrayList<>();
            for (RolePermission rolePermission : rolePermissions) {
                rolePermissionIds.add(rolePermission.getPermissionId().toString());
            }
            List<Permission> permissions = permissionMapper.selectBatchIds(rolePermissionIds);
//            ADD DELETE SELECT UPDATE
            userDetails.setPermissions(permissions);

            // 设置id

        } catch (Exception e) {
            throw new ServiceException("获取用户权限异常");
        }


        JWTSigner jwtSigner = JWTSignerUtil.hs512("yingyingying".getBytes(StandardCharsets.UTF_8));
        String token = JWTUtil.createToken(principal, jwtSigner);

        // 更新登录时间


        redisTemplate.opsForValue().set(token, userDetails, 24 * 60, TimeUnit.MINUTES);

        // 返回数据
        Map<String, Object> data = new HashMap<>();
        data.put("token", token);
        return Result.success(data);
    }


    @Override
    public LoginUser getUserInfo(String token) {
        Object obj = redisTemplate.opsForValue().get(token);
        if (obj != null) {
            // 将数据转成json数据
            return JSON.parseObject(JSON.toJSONString(obj), LoginUser.class);
        }
        return null;
    }

    public Result<?> logout(String token) {

        redisTemplate.delete(token);

        return Result.success();
    }


    /**
     * 获取用户列表
     *
     * @param user
     * @return
     */
    /**
     * 获取用户列表
     *
     * @param searchModel 包含查询参数的Map，包括分页信息和搜索条件
     * @return 返回一个Result对象，其中包含用户列表和总记录数
     */
    public Result<?> getUserList(Map<String, Object> searchModel, String token) {
        // 分页查询
        int pageNo = searchModel.get("pageNo") instanceof String ? Integer.parseInt((String) searchModel.get("pageNo")) : (Integer) searchModel.get("pageNo");
        int pageSize = searchModel.get("pageSize") instanceof String ? Integer.parseInt((String) searchModel.get("pageSize")) : (Integer) searchModel.get("pageSize");

        LambdaQueryWrapper<User> userWrapper = new LambdaQueryWrapper<>();
        // 正确逻辑：当字段非空时添加对应查询条件
        if (StringUtils.isNotBlank((String) searchModel.get("username"))) {
            userWrapper.like(User::getUsername, searchModel.get("username"));
        }
        if (StringUtils.isNotBlank((String) searchModel.get("phoneNumber"))) {
            userWrapper.like(User::getPhoneNumber, searchModel.get("phoneNumber"));
        }
        if (StringUtils.isNotBlank((String) searchModel.get("id"))) {
            userWrapper.eq(User::getId, searchModel.get("id"));
        }

        userWrapper.orderByDesc(User::getCreateTime);
        // 执行分页查询
        Page<User> userPage = this.baseMapper.selectPage(new Page<>(pageNo, pageSize), userWrapper);
        List<User> users = userPage.getRecords();
        List<User> newUsers = new ArrayList<>();

        Object obj = redisTemplate.opsForValue().get(token);
        User loginUser = null;
        if (obj != null) {
            // 将数据转成json数据
            loginUser = JSON.parseObject(JSON.toJSONString(obj), User.class);
        } else {
            throw new ServiceException("令牌过期，请重新登录");
        }

        for (User user : users) {
            if (user.getId().equals(adminRoleId)) {
                continue;
            }
            // 过滤自己
            if (user.getId().equals(loginUser.getId())) {
                continue;
            }

            user.setPassword(null);
            newUsers.add(user);
        }
        Map<String, Object> data = new HashMap<>();

        // 将查询到的用户列表和总记录数放入数据Map中
        data.put("users", newUsers);
        data.put("total", userPage.getTotal());

        // 返回成功结果，包含用户列表和总记录数
        return Result.success(data);
    }

    @Override
    public Result<?> updateUser(User user) {
        // 更具id查询
        User oldUser = this.baseMapper.selectById(user.getId());

        // 更具手机号码查询，判断是否存在
        LambdaQueryWrapper<User> userWrapper = new LambdaQueryWrapper<>();
        userWrapper.eq(User::getUsername, user.getUsername());
        User newUser = this.baseMapper.selectOne(userWrapper);

        if (newUser != null && !newUser.getId().equals(oldUser.getId())) {
            throw new ServiceException("手机号码已存在");
        }

        oldUser.setContent(user.getContent());
        oldUser.setUsername(user.getUsername());
        oldUser.setPhoneNumber(user.getPhoneNumber());
        oldUser.setStatus(user.getStatus());
        oldUser.setAvatar(user.getAvatar());


        this.baseMapper.updateById(oldUser);


        return Result.success("修改成功");
    }

    @Override
    public Result<?> register(User user) {
        // 判断手机号是否存在
        LambdaQueryWrapper<User> userWrapper = new LambdaQueryWrapper<>();

        userWrapper.eq(User::getUsername, user.getUsername());
        User newUser = this.baseMapper.selectOne(userWrapper);
        if (newUser != null) {
            throw new ServiceException("用户已存在");
        }


        // 设置ID
        user.setId(UUID.randomUUID().toString().replace("-", "").substring(0, 31));

        // 设置注册时间
        user.setCreateTime(LocalDateTime.now());

        // 密码加密 默认密码123456

        user.setPassword(bCryptPasswordEncoder.encode("123456"));

        // 保存用户
        this.baseMapper.insert(user);

        return Result.success("用户注册成功");
    }


    public Result<?> updatePassword(User user, String token) {


        // 查询用户名称
        User oldUser = null;
        if (user.getId() == null) {
            LoginUser userInfo = getUserInfo(token);
            oldUser = this.baseMapper.selectById(userInfo.getUser().getId());
        } else {
            oldUser = this.baseMapper.selectById(user.getId());
        }

        // 密码加密
        String newPassword = bCryptPasswordEncoder.encode(user.getPassword());

        oldUser.setPassword(newPassword);

        this.baseMapper.updateById(oldUser);

        // 退出登录
        redisTemplate.delete(token);


        return Result.success("修改密码成功");
    }

    /**
     * 设置用户权限用户权限
     *
     * @param userRole
     * @return
     */
    public Result<?> setUserRole(UserRole userRole) {

        // 查询数据库判断是否添加过权限
        LambdaQueryWrapper<UserRole> userRoleWrapper = new LambdaQueryWrapper<>();
        userRoleWrapper.eq(UserRole::getUserId, userRole.getUserId());
        UserRole oldUserRole = userRoleMapper.selectOne(userRoleWrapper);
        // 添加权限
        if (oldUserRole == null) {
            UserRole newUserRole = new UserRole();
            newUserRole.setId(UUID.randomUUID().toString());
            newUserRole.setUserId(userRole.getUserId());
            newUserRole.setRoleId(userRole.getRoleId());
            userRoleMapper.insert(newUserRole);
        } else {
            // 修改权限
            oldUserRole.setRoleId(userRole.getRoleId());
            userRoleMapper.updateById(oldUserRole);
        }

        return Result.success("修改成功");
    }

    public Result<?> getUserRole(String id) {
        // 查询用户角色
        LambdaQueryWrapper<UserRole> userRoleWrapper = new LambdaQueryWrapper<>();
        userRoleWrapper.eq(UserRole::getUserId, id);
        UserRole userRole = userRoleMapper.selectOne(userRoleWrapper);

        return Result.success(userRole);
    }

    // 查询所有非司机的普通用户的名称和id
    public Result<?> getUserOperations() {
        // 查询普通用户权限ID 135e7cc2-eafa-4375-bd2c-c3217877a56e 司机权限ID 18f2e1a7-af92-4579-a663-ce99f0061981

        LambdaQueryWrapper<UserRole> queryWrapper = new LambdaQueryWrapper<>();
        //
        queryWrapper.eq(UserRole::getRoleId, driverRoleId).or().eq(UserRole::getRoleId, userRoleId);

        // 查询所有非管理用户
        List<UserRole> userRoles = userRoleMapper.selectList(queryWrapper);

        List<String> ids = new ArrayList<>();

        for (UserRole userRole : userRoles) {
            ids.add(userRole.getUserId());
        }

        if (ids.size() == 0) {
            Map<String, Object> operation = new HashMap<>();
            operation.put("value", "");
            operation.put("label", "");

            List<Map<String, Object>> data = new ArrayList<>();
            data.add(operation);
            return Result.success(data);
        }

        List<User> users = this.baseMapper.selectBatchIds(ids);

        List<Map<String, Object>> data = new ArrayList<>();

        for (User user : users) {
            Map<String, Object> operation = new HashMap<>();
            operation.put("value", user.getId());
            operation.put("label", user.getUsername());

            data.add(operation);
        }

        return Result.success(data);
    }

    /**
     * 微信登录
     *
     * @param user
     * @return
     */
    @Override
    public Result<?> wxLogin(WxUserLogin user) {


        // 用户验证
        Authentication authentication = null;
        try {
            UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(user.getUsername(), user.getPassword());
            // 该方法会去调用UserDetailsServiceImpl.loadUserByUsername
            authentication = authenticationManager.authenticate(authenticationToken);
        } catch (Exception e) {
            throw new ServiceException(e.getMessage());
        }
        if (authentication == null) {
            throw new ServiceException("登录失败");
        }


        // 用户权限信息
        LoginUser userDetails = (LoginUser) authentication.getPrincipal();


        Map<String, Object> principal = new HashMap<>();
        principal.put("userId", userDetails.getUserId());
        principal.put("loginTime", LocalDateTime.now());

        // 查询用户角色
        try {
            LambdaQueryWrapper<UserRole> userRoleWrapper = new LambdaQueryWrapper<>();
            userRoleWrapper.eq(UserRole::getUserId, userDetails.getUserId());
            UserRole userRole = userRoleMapper.selectOne(userRoleWrapper);
            Role role = roleMapper.selectById(userRole.getRoleId());

            // 判断用户是否为当前角色
            if (!role.getName().equals(user.getRole())) {
                return Result.fail("用户角色错误");
            }

            // 查询角色对应的权限，并配置
            LambdaQueryWrapper<RolePermission> roleQueryWrapper = new LambdaQueryWrapper<>();
            roleQueryWrapper.eq(RolePermission::getRoleId, role.getId());
            List<RolePermission> rolePermissions = rolePermissionMapper.selectList(roleQueryWrapper);
            List<String> rolePermissionIds = new ArrayList<>();
            for (RolePermission rolePermission : rolePermissions) {
                rolePermissionIds.add(rolePermission.getPermissionId().toString());
            }
            List<Permission> permissions = permissionMapper.selectBatchIds(rolePermissionIds);
            // ADD DELETE SELECT UPDATE
            userDetails.setPermissions(permissions);

            // 设置id

        } catch (Exception e) {
            throw new ServiceException("获取用户权限异常");
        }


        JWTSigner jwtSigner = JWTSignerUtil.hs512("yingyingying".getBytes(StandardCharsets.UTF_8));
        String token = JWTUtil.createToken(principal, jwtSigner);

        // 更新登录时间


        redisTemplate.opsForValue().set(token, userDetails, 24 * 60, TimeUnit.MINUTES);

        // 返回数据
        Map<String, Object> data = new HashMap<>();
        data.put("token", token);
        return Result.success(data);
    }

    @Override
    public Result<?> updateSelfPassword(User user, String token) {
        // 查询用户名称
        LoginUser userInfo = getUserInfo(token);
        User oldUser = this.baseMapper.selectById(userInfo.getUser().getId());

        // 密码加密
        String newPassword = bCryptPasswordEncoder.encode(user.getPassword());

        oldUser.setPassword(newPassword);

        this.baseMapper.updateById(oldUser);

        // 退出登录
        redisTemplate.delete(token);

        return Result.success("修改密码成功");
    }

    @Override
    public Result<?> updateAv(User user) {
        User oldUser = this.baseMapper.selectById(user.getId());

        oldUser.setAvatar(user.getAvatar());

        this.baseMapper.updateById(oldUser);

        return Result.success("头像更换成功");
    }


}
